﻿using LightCAD.Core;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Text.Json.Serialization;
using System.Text.Json;
using System.Threading.Tasks;
using System.Reflection.Metadata;
using LightCAD.Core.Elements;
using System.Runtime.InteropServices;
using System.IO;
using System.Text.Json.Nodes;
using LightCAD.MathLib;
//using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace LightCAD.Runtime
{
    public class SectionManager
    {
        public static Dictionary<string, LcSection> Sections { get; private set; }
        private static string InitFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "sections.json");
        public static void Initilize()
        {
            Sections= new Dictionary<string, LcSection>();
            if (File.Exists(InitFileName))
            {
                var jstr = File.ReadAllText(InitFileName);
                if (string.IsNullOrEmpty(jstr))
                {
                    return;
                }
                var jele = JsonSerializer.Deserialize<List<JsonElement>>(jstr).ToList();
                for (var i=0;i< jele.Count;i++)
                {
                    JsonElement ele = jele[i];
                    var uuid = ele.ReadStringProperty("Uuid");
                    var name = ele.ReadStringProperty("Name");
                    var curve2ds = ele.ReadCurve2dListProperty("Segments");
                    var innerS = ele.ReadListProperty<List<JsonElement>>("InnerSegments");
                    var items = innerS.Select(n => n.Select(m => m.ReadCurve2dObject()).ToList());
                    var section=new LcSection();
                    section.Uuid = uuid;
                    section.Name = name;
                    section.Segments=curve2ds.ToList();
                    section.InnerSegments = items.ToList();
                    Sections.Add(uuid, section);
                }
            }
            else
            {
                File.Create(InitFileName);
            }

        }
        
        public static void AddSection(LcSection section)
        {
            Sections[section.Uuid] = section;
            var json = GetLcSectionJson(section);
            if (Sections.Count==1)
            {
                File.WriteAllText(InitFileName,"[\r\n" +json+ "\r\n]");
            }
            else
            {
                var jsons =  File.ReadLines(InitFileName).ToList();
                jsons.Insert(jsons.Count-1, "\r\n,\r\n"+ json);
                File.WriteAllLines(InitFileName, jsons);
            }
        }
        public static void RemoveSection(string uuid)
        {
            Sections.Remove(uuid);
            ResetSectionJson();
        }
        public static void ResetSectionJson()
        {
            if (File.Exists(InitFileName))
            {
                var jsons = string.Empty;
                foreach (var section in Sections.Values)
                {
                    var isClockWise = ShapeUtils.isClockWise(section.Segments.SelectMany(n => n.GetPoints((n is Arc2d ? 32 : 1))).ToListEx());
                    var newShape = new List<Curve2d>();
                    // var offset = this.InsertPoint.Clone().Negate();
                    for (var i = section.Segments.Count() - 1; i >= 0; i--)
                    {
                        var cur = section.Segments[i];
                        //cur.Translate(offset);
                        if (isClockWise)
                        {
                            cur.Reverse();
                            newShape.Add(cur.Clone());
                        }
                    }
                    if (isClockWise)
                        section.Segments = newShape;
                    jsons += GetLcSectionJson(section)+",";
 
                }
                File.WriteAllText(InitFileName, "[\r\n" + jsons.Substring(0,jsons.Length-1) + "\r\n]");

            }
        }

        private static string GetLcSectionJson(LcSection section)
        {
            JsonSerializerOptions options = new JsonSerializerOptions { ReadCommentHandling = JsonCommentHandling.Skip };
            JsonWriterOptions writerOptions = new() { Indented = true, Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping };
            using (MemoryStream stream = new())
            {
                using (Utf8JsonWriter writer = new(stream, writerOptions))
                {
                    writer.WriteStartObject();
                    writer.WriteString("Name", section.Name);
                    writer.WriteString("Uuid",section.Uuid);
                    writer.WriteStartArray(nameof(section.Segments));

                    foreach (var curve in section.Segments)
                    {
                        writer.WriteCurve2dObject(curve, options);
                    }
                    writer.WriteEndArray();
                    writer.WriteStartArray(nameof(section.InnerSegments));
                    foreach (var innersegment in section.InnerSegments)
                    {
                        writer.WriteStartArray();
                        foreach (var curve in innersegment)
                        {
                            writer.WriteCurve2dObject(curve, options);
                        }
                        writer.WriteEndArray();
                    }
                    writer.WriteEndArray();
                    writer.WriteEndObject();
                    writer.Flush();
                    string json = Encoding.UTF8.GetString(stream.ToArray());
                    return json;
                }
            }                         
        }
    }
}
